跳到主要内容

remote / @electron/remote 为什么废弃?和 invoke 相比差在哪?

考察点​

  • 对历史 API 的判断(还能不能用)
  • 同步跨进程调用的性能和安全问题

参考答案​

1. remote 当初做什么​

remote 让渲染进程像调用本地对象一样调用主进程模块:

// 旧写法,现在不要再写
const { BrowserWindow } = require('@electron/remote');
const win = BrowserWindow.getFocusedWindow();
win.minimize();

看起来省掉了 IPC 样板代码。Electron 14 从核心移除,社区包 @electron/remote 只是过渡,官方不再推荐。

2. 为什么废弃​

(1)每次属性访问都是同步 IPC

remote 用代理对象。渲染进程读 win.id、调用 win.minimize(),底层都是 sendSync,渲染进程主线程被卡住等主进程返回。一个看起来无害的循环就能把界面打卡。

(2)主进程对象泄漏到渲染进程

渲染进程拿到的是主进程对象的远程引用。页面脚本(含 XSS)可以沿着这个引用调用 BrowserWindow、dialog、甚至 require 主进程模块,权限边界消失。

(3)生命周期难推理

远程对象的垃圾回收靠引用计数消息,窗口关了引用还在,就会出现“调用已销毁对象”和内存不释放。

3. 正确替代​

能力收口到 preload,一次调用做完一件事:

// preload:只暴露“最小化当前窗口”
contextBridge.exposeInMainWorld('api', {
minimize: () => ipcRenderer.invoke('window:minimize'),
});

// 主进程:从 event 反查窗口,不把 BrowserWindow 交给页面
ipcMain.handle('window:minimize', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
win?.minimize();
});

和 remote 的差别:

remoteinvoke + 白名单
阻塞同步,卡渲染进程异步,不卡 UI
暴露面整个主进程模块一个函数一件事
参数渲染进程可任意调用方法主进程校验参数
销毁远程引用容易悬空调用时现查窗口

4. 迁移时怎么搜​

全局搜 require('electron').remote、@electron/remote、enableRemoteModule。enableRemoteModule 这个开关本身也已删除,老项目升级会直接报错。

面试话术​

remote 的问题是把主进程对象代理到渲染进程:每次属性访问都是同步 IPC,页面还能顺着引用调用任意主进程能力。替代方式是 invoke 加语义化 API,窗口身份从 event.sender 反查,不把 BrowserWindow 交出去。看到项目还在用 @electron/remote,我会把它当成待迁移债务,而不是新功能的写法。

常见追问​

  • @electron/remote 现在还能跑吗? 能装上,但新版本 Electron 上行为越来越脆,只适合老项目过渡,不适合新代码。
  • 有没有必须同步拿主进程数据的场景? 几乎没有。启动配置也改成窗口显示前 invoke 一次,不要 sendSync。